package com.sky.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.sky.constant.MessageConstant;
import com.sky.constant.StatusConstant;
import com.sky.dto.DishDTO;
import com.sky.dto.SetmealDTO;
import com.sky.dto.SetmealPageQueryDTO;
import com.sky.entity.Dish;
import com.sky.entity.Setmeal;
import com.sky.entity.SetmealDish;
import com.sky.exception.DeletionNotAllowedException;
import com.sky.mapper.DishMapper;
import com.sky.mapper.SetmealDishMapper;
import com.sky.mapper.SetmealMapper;
import com.sky.result.PageResult;
import com.sky.result.Result;
import com.sky.service.SetmealService;
import com.sky.vo.DishItemVO;
import com.sky.vo.DishVO;
import com.sky.vo.SetmealVO;
import nonapi.io.github.classgraph.json.Id;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @program: sky-take-out
 * @description:
 * @author: 酷炫焦少
 * @create: 2024-11-17 15:07
 **/
@Service
public class SetmealServiceImpl implements SetmealService {

    @Resource
    private SetmealMapper setmealMapper;

    @Resource
    private SetmealDishMapper setmealDishMapper;

    @Resource
    private DishMapper dishMapper;

    @Resource
    private RedisTemplate<Object, Object> redisTemplate;

    private Result<String> setmealResult(SetmealDTO setmealDTO) {
        if (Objects.isNull(setmealDTO)) {
            return Result.error("添加套餐失败");
        }
        if (StrUtil.isBlank(setmealDTO.getName())) {
            return Result.error("套餐名称不能为空");
        }
        BigDecimal price = setmealDTO.getPrice();
        if (Objects.isNull(price) || price.scale() > 2) {
            return Result.error("套餐价格输入错误，请重新输入");
        }
        if (setmealDTO.getDescription().length() > 200) {
            return Result.error("套餐描述超过200字");
        }
        return null;
    }

    @Override
    @Transactional
    public Result<String> addSetmeal(SetmealDTO setmealDTO) {
        Result<String> r = setmealResult(setmealDTO);
        if (!Objects.isNull(r)) {
            return r;
        }
        Setmeal setmeal = BeanUtil.copyProperties(setmealDTO, Setmeal.class);
        int result = setmealMapper.saveSetmeal(setmeal);
        if (result < 1) {
            return Result.error("添加套餐失败");
        }
        List<SetmealDish> setmealDishes = setmealDTO.getSetmealDishes();
        setmealDishMapper.saveSetmealDish(setmealDishes, setmeal.getId());
        redisTemplate.delete("setmeal:" + setmealDTO.getCategoryId());
        return Result.success("添加套餐成功");
    }

    @Override
    public Result<List<SetmealVO>> list(Long categoryId) {
        String setmealStr = (String) redisTemplate.opsForValue().get("setmeal:" + categoryId);
        if (StrUtil.isNotBlank(setmealStr)) {
            List<SetmealVO> setmealVOList = JSON.parseArray(setmealStr, SetmealVO.class);
            return Result.success(setmealVOList);
        }
        Setmeal setmeal = Setmeal.builder()
                .categoryId(categoryId)
                .status(StatusConstant.ENABLE)
                .build();
        List<SetmealVO> setmealVOList = setmealMapper.querySetmealList(setmeal);
        if (CollectionUtil.isEmpty(setmealVOList)) {
            return Result.success(Collections.emptyList());
        }
        redisTemplate.opsForValue().set("setmeal:" + categoryId, JSON.toJSONString(setmealVOList));
        return Result.success(setmealVOList);
    }

    @Override
    public Result<PageResult> page(SetmealPageQueryDTO setmealPageQueryDTO) {
        PageHelper.startPage(setmealPageQueryDTO.getPage(), setmealPageQueryDTO.getPageSize());
        Setmeal setmeal = BeanUtil.copyProperties(setmealPageQueryDTO, Setmeal.class);
        List<SetmealVO> setmeals = setmealMapper.querySetmealList(setmeal);
        if (CollectionUtil.isEmpty(setmeals)) {
            return Result.success(new PageResult(0, Collections.emptyList()));
        }
        PageInfo<SetmealVO> pageInfo = new PageInfo<>(setmeals);
        return Result.success(new PageResult(pageInfo.getTotal(), pageInfo.getList()));
    }

    @Override
    public Result<String> editStatus(Integer status, Long id) {
        if (Objects.isNull(id)) {
            return Result.error("请选择你要更改的套餐");
        }
        if (status == 1) {
            int count = setmealDishMapper.countStatusBySetmealId(id, StatusConstant.DISABLE);
            if (count > 0) {
                throw new DeletionNotAllowedException(MessageConstant.SETMEAL_ENABLE_FAILED);
            }
        }
        Long categoryId = setmealMapper.queryCategoryIdByid(id);
        Setmeal setmeal = Setmeal.builder()
                .status(status)
                .id(id)
                .build();
        int result = setmealMapper.updateStatus(setmeal);
        if (result < 1) {
            return Result.error("更改失败");
        }
        redisTemplate.delete("setmeal:" + categoryId);
        return Result.success("更改成功");
    }

    @Override
    public Result<SetmealVO> getSetmealById(Long id) {
        if (Objects.isNull(id)) {
            return Result.error("请选择你要查询的套餐");
        }
        SetmealVO setmealVO = setmealMapper.querySetmealById(id);
        if (Objects.isNull(setmealVO)) {
            return Result.error("暂无该套餐");
        }
        List<SetmealDish> setmealDishes = setmealDishMapper.querySetmealBySetmealId(id);
        setmealVO.setSetmealDishes(setmealDishes);
        return Result.success(setmealVO);
    }

    @Override
    @Transactional
    public Result<String> editSetmeal(SetmealDTO setmealDTO) {
        Result<String> r = setmealResult(setmealDTO);
        if (!Objects.isNull(r)) {
            return r;
        }
        Long oldCategoryId = setmealMapper.queryCategoryIdByid(setmealDTO.getId());
        Long newCategoryId = setmealDTO.getCategoryId();
        Setmeal setmeal = BeanUtil.copyProperties(setmealDTO, Setmeal.class);
        int result = setmealMapper.updateSetmeal(setmeal);
        if (result < 1) {
            return Result.error("更新套餐失败");
        }
        Long setmealId = setmealDTO.getId();
        List<SetmealDish> setmealDishes = setmealDTO.getSetmealDishes();
        setmealDishMapper.deleteBySetmealIds(Collections.singletonList(setmealId));
        setmealDishMapper.saveSetmealDish(setmealDishes, setmealId);
        if (!Objects.equals(oldCategoryId, newCategoryId)) {
            redisTemplate.delete("setmeal:" + oldCategoryId);
            redisTemplate.delete("setmeal:" + newCategoryId);
        } else {
            redisTemplate.delete("setmeal:" + oldCategoryId);
        }
        return Result.success("更新成功");
    }

    @Override
    public Result<String> deleteSetmeal(List<Long> ids) {
        int count = setmealMapper.countStatus(StatusConstant.ENABLE, ids);
        if (count > 0) {
            throw new DeletionNotAllowedException(MessageConstant.SETMEAL_ON_SALE);
        }
        int result = setmealMapper.deleteSetmealByIds(ids);
        if (result < 1) {
            return Result.error("删除失败");
        }
        setmealDishMapper.deleteBySetmealIds(ids);
        return Result.success("删除成功");
    }

    @Override
    public Result<List<DishItemVO>> getDishItemById(Long id) {
        List<DishItemVO> dishItemVOList = dishMapper.queryDishItemVoList(id);
        if (CollectionUtil.isEmpty(dishItemVOList)) {
            return Result.success(Collections.emptyList());
        }
        return Result.success(dishItemVOList);
    }

}
